package mobi.weq.util;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import mobi.weq.model.User;
import mobi.weq.util.edinburgh.EdinburghMap;

public class Util {
	public static void main(String[] args) {
		Date d = new Date();
		for (int i = 0; i < 10; i++) {
			System.out.println(d);
			d = Util.decreaseDateByDay(d, 1);
		}
	}

	public static User getUserFromSession(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		HttpSession session = req.getSession(true);
		User user = (User) session.getAttribute("user");
		if (user != null) {
			return user;
		} else {
			resp.sendRedirect(req.getServletContext().getContextPath() + "/login");
			return null;
		}
	}

	public static void printObject(Object o) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Method[] methods = o.getClass().getDeclaredMethods();
		for (Method method : methods) {
			String name = method.getName();
			if (name.startsWith("get") || name.startsWith("is")) {
				System.out.println(method.getName() + ":" + method.invoke(o, null));
			}
		}
	}

	public static double getGaussian(double mean, double variance) {
		Random random = new Random();
		return mean + random.nextGaussian() * variance;
	}

	public static Date decreaseDateByHour(Date date, int i) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date); // convert date to Calendar object
		int hoursToDecrement = -1 * i;
		cal.add(Calendar.HOUR, hoursToDecrement);
		date = cal.getTime(); // again get back date object
		return date;
	}

	public static Date decreaseDateByDay(Date date, int i) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date); // convert date to Calendar object
		int daysToDecrement = -1 * i;
		cal.add(Calendar.DATE, daysToDecrement);
		date = cal.getTime(); // again get back date object
		return date;
	}

	public static String getTableName(String prefix, Date d) {
		return prefix + "_" + d.getDate() + "_" + (d.getMonth() + 1) + "_" + (d.getYear() + 1900);
	}

	public static String getNDaysBackTableFromDate(String prefix, int nDays, Date d) {
		d = Util.decreaseDateByDay(d, nDays);
		return prefix + "_" + d.getDate() + "_" + (d.getMonth() + 1) + "_" + (d.getYear() + 1900);
	}

	public static void goHome(HttpServletRequest request, HttpServletResponse response) throws IOException {
		response.sendRedirect(request.getServletContext().getContextPath() + "/home");
	}

	public static String getGridId(double lat, double lng) {
		lat = ((int) (lat * EdinburghMap.GRID_DENSITY)) / EdinburghMap.GRID_DENSITY;
		lng = ((int) (lng * EdinburghMap.GRID_DENSITY)) / EdinburghMap.GRID_DENSITY;
		return lat + "#" + lng;
	}

	public static void printProgress(int done, int total) {
		double percentage = (1.0 * done) / total;
		int sticks = (int) (percentage * 50);
		percentage *= 100;

		String progress = "";
		for (int i = 0; i < sticks; i++) {
			progress += "|";
		}
		for (int i = sticks; i < 50; i++) {
			progress += ".";
		}
		System.out.println(progress + " (" + ((int) percentage) + "%)");
	}

	public static boolean coordsLieInEdinburgh(double lat, double lng) {
		return lat >= EdinburghMap.LAT1 && lat <= EdinburghMap.LAT2 && lng >= EdinburghMap.LNG1 && lng <= EdinburghMap.LNG2;
	}
}
